// Written by .:..: (2009)
Class ServerStStats extends KFSteamStatsAndAchievements;

var ClientPerkRepLink Rep;
var StatsObject MyStatsObject;
var KFPlayerController PlayerOwner;
var ServerPerksMut MutatorOwner;
var bool bHasChanged,bStatsChecking,bStHasInit,bHadSwitchedVet,bSwitchIsOKNow,bStatsReadyNow;
var string ClanName;

var class<SRVeterancyTypes> SelectingPerk;

final function int GetID()
{
	return MyStatsObject.ID;
}
final function SetID( int ID )
{
	MyStatsObject.ID = ID;
}

function PreBeginPlay()
{
	if( Rep==None )
	{
		Rep = Spawn(Class'ClientPerkRepLink',Owner);
		Rep.StatObject = Self;
	}
	Super.PreBeginPlay();
}
function PostBeginPlay()
{
	if( Rep!=None )
		Rep.SpawnCustomLinks();

	bStatsReadyNow = !MutatorOwner.bUseRemoteDatabase;
	PlayerOwner = KFPlayerController(Owner);
	MyStatsObject = MutatorOwner.GetStatsForPlayer(PlayerOwner);
	KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkill = None;
	if( !bStatsReadyNow )
	{
		Timer();
		SetTimer(1+FRand(),true);
		return;
	}
	bSwitchIsOKNow = true;
	SetUnPlayerName();
	if( MyStatsObject!=None )
	{
		RepCopyStats();
		bHasChanged = true;
		CheckPerks(true);
		ServerSelectPerkName(MyStatsObject.GetSelectedPerk());
	}
	else CheckPerks(true);
	if( MutatorOwner.bForceGivePerk && KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkill==None )
		ServerSelectPerk(Rep.PickRandomPerk());
	bSwitchIsOKNow = false;
	SetTimer(0.1,false);
	SRPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClanName = MyStatsObject.ClanName;
}

function SetUnPlayerName()
{
	if(MyStatsObject.UName!="")
	{
		if(PlayerOwner.PlayerReplicationInfo.PlayerName!=MyStatsObject.UName)
		{
			Log("Forcing change: Name"@PlayerOwner.PlayerReplicationInfo.PlayerName@"into"@MyStatsObject.UName);
		}
		PlayerOwner.PlayerReplicationInfo.PlayerName = MyStatsObject.UName;
	}
}

final function ChangeCharacter( string CN )
{
	PlayerOwner.PawnSetupRecord = class'xUtil'.static.FindPlayerRecord(CN);
	if( PlayerOwner.PawnSetupRecord.VoiceClassName!="" )
		PlayerOwner.PlayerReplicationInfo.SetCharacterVoice(PlayerOwner.PawnSetupRecord.VoiceClassName);
	PlayerOwner.PlayerReplicationInfo.SetCharacterName(CN);
}

final function GetData( string D )
{
	bStatsReadyNow = true;
	MyStatsObject.SetSaveData(D);
	RepCopyStats();
	bHasChanged = true;
	bSwitchIsOKNow = true;

	// Apply selected character.             ////////////////////////////
	if( MyStatsObject.SelectedChar!="" )
		ChangeCharacter(MyStatsObject.SelectedChar);

	CheckPerks(true);
	ServerSelectPerkName(MyStatsObject.GetSelectedPerk());
	Rep.SendClientPerks();
	if( MutatorOwner.bForceGivePerk && KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkill==None )
		ServerSelectPerk(Rep.PickRandomPerk());
	bSwitchIsOKNow = false;
	SetTimer(0.1,false);
}
function Timer()
{
	if( !bStatsReadyNow )
	{
		MutatorOwner.GetRemoteStatsForPlayer(Self);
		return;
	}
	if( !bStHasInit )
	{
		if( PlayerOwner.SteamStatsAndAchievements!=None && PlayerOwner.SteamStatsAndAchievements!=Self )
			PlayerOwner.SteamStatsAndAchievements.Destroy();
		PlayerOwner.SteamStatsAndAchievements = Self;
		PlayerOwner.PlayerReplicationInfo.SteamStatsAndAchievements = Self;
		bStHasInit = true;
		Rep.SendClientPerks();
	}
	if( bStatsChecking )
	{
		bStatsChecking = false;
		CheckPerks(false);
	}
}
final function RepCopyStats()
{
	Rep.RDamageHealedStat = MyStatsObject.DamageHealedStat;
	Rep.RMassHealPoints = MyStatsObject.mMH;
	Rep.RCalmedPounds = MyStatsObject.mCFP;

	Rep.RWeldingPointsStat = MyStatsObject.WeldingPointsStat;
	Rep.RShotgunDamageStat = MyStatsObject.ShotgunDamageStat;
	Rep.RspHeavyMonsterPoints = MyStatsObject.spHM;

	Rep.RHeadshotKillsStat = MyStatsObject.HeadshotKillsStat;
	Rep.RHeadShotHuskPoints = MyStatsObject.ssHu;
	Rep.RssHeavyMonsterPoints = MyStatsObject.ssHM;
	Rep.RHeadShotMPKillsStat = MyStatsObject.ssMP;

	Rep.RBullpupDamageStat = MyStatsObject.BullpupDamageStat;
	Rep.RStalkerKillsStat = MyStatsObject.StalkerKillsStat;
	Rep.RcmHeavyMonsterPoints = MyStatsObject.cmHM;

	Rep.RMeleeDamageStat = MyStatsObject.MeleeDamageStat;
	Rep.RMeleeGoreFastKillsStat = MyStatsObject.bGo;
	Rep.RbHeavyMonsterPoints = MyStatsObject.bHM;

	Rep.RFlameThrowerDamageStat = MyStatsObject.FlameThrowerDamageStat;
	Rep.RBurnedCrawlersStat = MyStatsObject.fCr;
	Rep.RfHeavyMonsterPoints = MyStatsObject.fHM;

	Rep.RExplosivesDamageStat = MyStatsObject.ExplosivesDamageStat;
	Rep.RPipeBombDamageStat = MyStatsObject.dmPB;
	Rep.RdmHeavyMonsterPoints = MyStatsObject.dmHM;

	Rep.RSoleSurvivorWavesStat = MyStatsObject.SoleSurvivorWavesStat;
	Rep.RKillsStat = MyStatsObject.KillsStat;
	Rep.TotalPlayTime = MyStatsObject.TotalPlayTime;
	Rep.WinsCount = MyStatsObject.WinsCount;
	Rep.LostsCount = MyStatsObject.LostsCount;

	MyStatsObject.GetCustomValues(Rep.CustomLink);
}

final function ServerSelectPerkName( name N )
{
	local byte i;

	if( N=='' )
		return;

	for( i=0; i<Rep.CachePerks.Length; i++ )
	{
		if( Rep.CachePerks[i].PerkClass.Name==N )
		{
			ServerSelectPerk(Rep.CachePerks[i].PerkClass);
			break;
		}
	}
}
final function ServerSelectPerk( Class<SRVeterancyTypes> VetType )
{
	local byte i;

	if( !bStatsReadyNow )
		return;
	if( VetType==None || !SelectionOK(VetType) )
	{
		if( !bSwitchIsOKNow )
			PlayerOwner.ClientMessage("Your desired perk is unavailable.");
		return;
	}
	else if( KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkill==VetType )
	{
		if( SelectingPerk!=None )
		{
			SelectingPerk = None;
			PlayerOwner.ClientMessage("You will remain the same perk now.");
		}
		return;
	}
	if( MyStatsObject!=None )
		MyStatsObject.SetSelectedPerk(VetType.Name);
	if( 	!Level.Game.bWaitingToStartMatch && !bSwitchIsOKNow && 
			(KFGameReplicationInfo(Level.GRI).bWaveInProgress || bHadSwitchedVet) && 
			PlayerOwner.Pawn!=None )
	{
		PlayerOwner.ClientMessage(Repl(PlayerOwner.YouWillBecomePerkString, "%Perk%", VetType.Default.VeterancyName));
		SelectingPerk = VetType;
		PlayerOwner.SelectedVeterancy = VetType; // Force KFGameType update this.
		return;
	}
	if( !bSwitchIsOKNow )
		bHadSwitchedVet = true;
	SelectingPerk = None;
	for( i=0; i<Rep.CachePerks.Length; i++ )
	{
		if( Rep.CachePerks[i].PerkClass==VetType )
		{
			if( Rep.CachePerks[i].CurrentLevel==0 )
				return;
			PlayerOwner.SelectedVeterancy = VetType;
			KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkill = VetType;
			KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkillLevel = Rep.CachePerks[i].CurrentLevel-1;
			if( SRKFHumanPawn(PlayerOwner.Pawn)!=None )
			{
				SRKFHumanPawn(PlayerOwner.Pawn).VeterancyChanged();
				DropToCarryLimit(SRKFHumanPawn(PlayerOwner.Pawn));
			}
		}
	}
}

final function ForceServerSelectPerk( Class<SRVeterancyTypes> VetType, int forcedLevel )
{
	local byte i;

	if( MyStatsObject!=None )
		MyStatsObject.SetSelectedPerk(VetType.Name);
	if( !bSwitchIsOKNow )
		bHadSwitchedVet = true;
	SelectingPerk = None;
	for( i=0; i<Rep.CachePerks.Length; i++ )
	{
		if( Rep.CachePerks[i].PerkClass==VetType )
		{
			if( Rep.CachePerks[i].CurrentLevel==0 )
				return;
			PlayerOwner.SelectedVeterancy = VetType;
			KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkill = VetType;
			if(forcedLevel==-1)
				KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkillLevel = Rep.CachePerks[i].CurrentLevel-1;
			else
				KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkillLevel = forcedLevel;
			if( SRKFHumanPawn(PlayerOwner.Pawn)!=None )
			{
				SRKFHumanPawn(PlayerOwner.Pawn).VeterancyChanged();
			}
		}
	}
}

final function DropToCarryLimit( SRKFHumanPawn P )
{
	local byte c;
	local Inventory I;

	while( P.CurrentWeight>P.MaxCarryWeight && ++c<6 )
	{
		for ( I = P.Inventory; I != none; I = I.Inventory )
		{
			if ( KFWeapon(I) != none && !KFWeapon(I).bKFNeverThrow )
			{
				I.Velocity = P.Velocity;
				I.DropFrom(P.Location + VRand() * 10);
				break; // Drop weapons until player is capable of carrying them all.
			}
		}
	}
}

final function bool SelectionOK( Class<SRVeterancyTypes> VetType )
{
	local byte i;

	for( i=0; i<Rep.CachePerks.Length; i++ )
	{
		if( Rep.CachePerks[i].PerkClass==VetType )
			return (Rep.CachePerks[i].CurrentLevel>0);
	}
	return false;
}
final function CheckPerks( bool bInit )
{
	local byte i,NewLevel;

	if( !bStatsReadyNow )
		return;
	if( bInit )
	{
		for( i=0; i<Rep.CachePerks.Length; i++ )
			Rep.CachePerks[i].CurrentLevel = Rep.CachePerks[i].PerkClass.Static.PerkIsAvailable(Rep);
		return;
	}
	for( i=0; i<Rep.CachePerks.Length; i++ )
	{
		if( Rep.CachePerks[i].CurrentLevel<=Rep.MaximumLevel )
		{
			
			NewLevel = Rep.CachePerks[i].PerkClass.Static.PerkIsAvailable(Rep);
			//Log("LevelUP!"@NewLevel@Rep.CachePerks[i].CurrentLevel);
			if( NewLevel>Rep.CachePerks[i].CurrentLevel )
			{
				if( Class<SRVeterancyTypes>(KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkill)==Rep.CachePerks[i].PerkClass )
					KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkillLevel = NewLevel-1;
				Rep.CachePerks[i].CurrentLevel = NewLevel;
				Rep.ClientPerkLevel(i,NewLevel);
				//Log("LevelUP 2 MutatorOwner.bMessageAnyPlayerLevelUp"@MutatorOwner.bMessageAnyPlayerLevelUp);
				if( 1==1 )//MutatorOwner.bMessageAnyPlayerLevelUp )
				{
					//Log("Broadcasting");
					BroadcastLocalizedMessage(Class'KFVetEarnedMessagePL',(NewLevel-1),PlayerOwner.PlayerReplicationInfo,,Rep.CachePerks[i].PerkClass);
				}
			}
		}
	}
}
final function DelayedStatCheck()
{
	if( MyStatsObject!=None )
		MyStatsObject.bStatsChanged = true;
	if( bStatsChecking || !bStatsReadyNow )
		return;
	bStatsChecking = true;
	SetTimer(1,false);
}

function MatchEnded()
{
}
function AddDamageHealed(int Amount, optional bool bMP7MHeal, optional bool bMP5MHeal)
{
	//Flame
	if(!KFGameType(Level.Game).bWaveInProgress)
		return;
	//
	bHasChanged = true;
	Rep.RDamageHealedStat+=Amount;
	if( MyStatsObject!=None )
		MyStatsObject.DamageHealedStat+=Amount;
	DelayedStatCheck();
}

function AddWeldingPoints(int Amount)
{
	//Flame
	if(!KFGameType(Level.Game).bWaveInProgress)
		return;
	//
	bHasChanged = true;
	Rep.RWeldingPointsStat+=Amount;
	if( MyStatsObject!=None )
		MyStatsObject.WeldingPointsStat+=Amount;
	DelayedStatCheck();
}
function AddShotgunDamage(int Amount)
{
	bHasChanged = true;
	Rep.RShotgunDamageStat+=Amount;
	if( MyStatsObject!=None )
		MyStatsObject.ShotgunDamageStat+=Amount;
	DelayedStatCheck();
}
function AddHeadshotKill(bool bLaserSightedEBRHeadshot)
{
	bHasChanged = true;
	Rep.RHeadshotKillsStat++;
	if( MyStatsObject!=None )
		MyStatsObject.HeadshotKillsStat++;
	DelayedStatCheck();
}
function AddStalkerKill()
{
	bHasChanged = true;
	Rep.RStalkerKillsStat++;
	if( MyStatsObject!=None )
		MyStatsObject.StalkerKillsStat++;
	DelayedStatCheck();
}
function AddBullpupDamage(int Amount)
{
	bHasChanged = true;
	Rep.RBullpupDamageStat+=Amount;
	if( MyStatsObject!=None )
		MyStatsObject.BullpupDamageStat+=Amount;
	DelayedStatCheck();
}

function AddMeleeDamage(int Amount)
{
	bHasChanged = true;
	Rep.RMeleeDamageStat+=Amount;
	if( MyStatsObject!=None )
		MyStatsObject.MeleeDamageStat+=Amount;
	DelayedStatCheck();
}

function AddFlameThrowerDamage(int Amount)
{
	bHasChanged = true;
	Rep.RFlameThrowerDamageStat+=Amount;
	if( MyStatsObject!=None )
		MyStatsObject.FlameThrowerDamageStat+=Amount;
	DelayedStatCheck();
}
function WaveEnded()
{
	if( SelectingPerk!=None )
	{
		bHadSwitchedVet = false;
		bSwitchIsOKNow = true;
		ServerSelectPerk(SelectingPerk);
		bSwitchIsOKNow = false;
	}
}
//function AddKill(bool bLaserSightedEBRM14Headshotted)
function AddKill(bool bLaserSightedEBRM14Headshotted, bool bMeleeKill, bool bZEDTimeActive, bool bM4Kill, bool bBenelliKill, bool bRevolverKill, bool bMK23Kill, bool bFNFalKill, bool bBullpupKill, string MapName)
{
	bHasChanged = true;
	Rep.RKillsStat++;
	if( MyStatsObject!=None )
		MyStatsObject.KillsStat++;
	DelayedStatCheck();
}
//function AddBloatKill()
function AddBloatKill(bool bWithBullpup)
{
/* 	bHasChanged = true;
	Rep.RBloatKillsStat++;
	if( MyStatsObject!=None )
		MyStatsObject.BloatKillsStat++;
	DelayedStatCheck(); */
}

//function AddSirenKill()
function AddSirenKill(bool bLawRocketImpact)
{
/* 	bHasChanged = true;
	Rep.RSirenKillsStat++;
	if( MyStatsObject!=None )
		MyStatsObject.SirenKillsStat++;
	DelayedStatCheck(); */
}

function AddStalkerKillWithExplosives()
{
/* 	bHasChanged = true;
	Rep.RStalkersKilledWithExplosivesStat++;
	if( MyStatsObject!=None )
		MyStatsObject.StalkersKilledWithExplosivesStat++;
	DelayedStatCheck(); */
}

function AddFireAxeKill();
function AddChainsawScrakeKill();

function AddBurningCrossbowKill()
{
/* 	bHasChanged = true;
	Rep.RBurningCrossbowKillsStat++;
	if( MyStatsObject!=None )
		MyStatsObject.BurningCrossbowKillsStat++;
	DelayedStatCheck(); */
}

function AddFeedingKill()
{
/* 	bHasChanged = true;
	Rep.RFeedingKillsStat++;
	if( MyStatsObject!=None )
		MyStatsObject.FeedingKillsStat++;
	DelayedStatCheck(); */
}

function OnGrenadeExploded();
function AddGrenadeKill();
function OnShotHuntingShotgun();
function AddHuntingShotgunKill();
function KilledEnemyWithBloatAcid();
//function KilledFleshpound(bool bWithMeleeAttack, bool bWithAA12);
function KilledFleshpound(bool bWithMeleeAttack, bool bWithAA12, bool bWithKnife, bool bWithClaymore);
function AddMedicKnifeKill();

function AddGibKill(bool bWithM79)
{
/* 	bHasChanged = true;
	Rep.RGibbedEnemiesStat++;
	if( MyStatsObject!=None )
		MyStatsObject.GibbedEnemiesStat++;
	DelayedStatCheck(); */
}

function AddFleshpoundGibKill()
{
/* 	bHasChanged = true;
	Rep.RGibbedFleshpoundsStat++;
	if( MyStatsObject!=None )
		MyStatsObject.GibbedFleshpoundsStat++;
	DelayedStatCheck(); */
}

function AddSelfHeal()
{
/* 	bHasChanged = true;
	Rep.RSelfHealsStat++;
	if( MyStatsObject!=None )
		MyStatsObject.SelfHealsStat++;
	DelayedStatCheck(); */
}

function AddOnlySurvivorOfWave()
{
	bHasChanged = true;
	Rep.RSoleSurvivorWavesStat++;
	if( MyStatsObject!=None )
		MyStatsObject.SoleSurvivorWavesStat++;
	DelayedStatCheck();
}

function AddDonatedCash(int Amount)
{
/* 	bHasChanged = true;
	Rep.RCashDonatedStat+=Amount;
	if( MyStatsObject!=None )
		MyStatsObject.CashDonatedStat+=Amount;
	DelayedStatCheck(); */
}

function AddZedTime(float Amount)
{
	bHasChanged = true;
	Rep.RTotalZedTimeStat+=Amount;
	if( MyStatsObject!=None )
		MyStatsObject.TotalZedTimeStat+=Amount;
}

function AddExplosivesDamage(int Amount)
{
	bHasChanged = true;
	Rep.RExplosivesDamageStat+=Amount;
	if( MyStatsObject!=None )
		MyStatsObject.ExplosivesDamageStat+=Amount;
}

function WonLostGame( bool bDidWin )
{
	if( bDidWin )
	{
		++Rep.WinsCount;
		if( MyStatsObject!=None )
			++MyStatsObject.WinsCount;
	}
	else
	{
		++Rep.LostsCount;
		if( MyStatsObject!=None )
			++MyStatsObject.LostsCount;
	}
	bHasChanged = true;
	DelayedStatCheck();
	GoToState('');
}
//-------------------------------------------SH

function AddDamageHealedWithM56(int Amount)
{
	if(!KFGameType(Level.Game).bWaveInProgress)
		return;
	bHasChanged = true;
	Rep.RMassHealPoints+=Amount;
	if( MyStatsObject!=None )
		MyStatsObject.mMH+=Amount;
	DelayedStatCheck();
}

function AddCalmedPound()
{
	bHasChanged = true;
	Rep.RCalmedPounds++;
	if( MyStatsObject!=None )
		MyStatsObject.mCFP++;
	DelayedStatCheck();
}

function AddspHMDamage(int Amount)
{
	bHasChanged = true;
	Rep.RspHeavyMonsterPoints+=Amount;
	if( MyStatsObject!=None )
		MyStatsObject.spHM+=Amount;
	DelayedStatCheck();
}

function AddHeadShotHuskKill()
{
	bHasChanged = true;
	Rep.RHeadShotHuskPoints++;
	if( MyStatsObject!=None )
		MyStatsObject.ssHu++;
	DelayedStatCheck();
}

function AddHeadShotHMPoints(KFMonster kfM,KFPlayerController Killer)
{
	local int N;
	local KFPlayerReplicationInfo KFPRI;
	KFPRI=KFPlayerReplicationInfo(Killer.PlayerReplicationInfo);
	if(KFPRI.ClientVeteranSkillLevel < 10 || KFPRI.ClientVeteranSkill.Name != 'SRVetSharpshooter')
		return;
	N=0;
	bHasChanged = true;
	if	(	kfM.IsA('ZombieScrake')	||	kfM.IsA('shZombieScrake_XMAS')	)
	{
		N=1;
		//Log("ZombieScrake/ZombieBrute in state"@kfM.GetStateName()@N);
	}
	if	(	kfM.IsA('ZombieFleshPound')	||	kfM.IsA('shZombieFleshPound_XMAS')	)
	{
		N=2;
		if(kfM.GetStateName()=='RageCharging')
			N*=2;
		//Log("FP in state"@kfM.GetStateName()@N);
	}
	if	(	kfM.IsA('ZombieMeatPounder')	)
	{
		N=8;
		if(kfM.GetStateName()=='RageCharging')
			N*=2;
		AddHeadShotMeatPounderKill();
		//Log("MP in state"@kfM.GetStateName()@N);
	}
	if	(	kfM.IsA('ZombieMauler')	)
	{
		N=4;
		//Log("Mauler in state"@kfM.GetStateName()@N);
	}
	if	(	kfM.IsA('ExZombieBoss')	||	kfM.IsA('shZombieBoss_XMAS'))
	{
		N=64;
		//Log("Boss in state"@kfM.GetStateName());
	}
	Rep.RssHeavyMonsterPoints+=N;
	if( MyStatsObject!=None )
		MyStatsObject.ssHM+=N;
	DelayedStatCheck();
}

function AddHeadShotMeatPounderKill()
{
	Rep.RHeadShotMPKillsStat++;
	if( MyStatsObject!=None )
		MyStatsObject.ssMP++;
	DelayedStatCheck();
}

function AddcmHMDamage(int Amount)
{
	bHasChanged = true;
	Rep.RcmHeavyMonsterPoints+=Amount;
	if( MyStatsObject!=None )
		MyStatsObject.cmHM+=Amount;
	DelayedStatCheck();
}

function AddMeleeGoreFastKill()
{
	bHasChanged = true;
	Rep.RMeleeGoreFastKillsStat++;
	if( MyStatsObject!=None )
		MyStatsObject.bGo++;
	DelayedStatCheck();
}

function AddbHMDamage(int Amount)
{
	bHasChanged = true;
	Rep.RbHeavyMonsterPoints+=Amount;
	if( MyStatsObject!=None )
		MyStatsObject.bHM+=Amount;
	DelayedStatCheck();
}

function AddBurnedCrawlers()
{
	bHasChanged = true;
	Rep.RBurnedCrawlersStat++;
	if( MyStatsObject!=None )
		MyStatsObject.fCr++;
	DelayedStatCheck();
}

function AddfHMDamage(int Amount)
{
	bHasChanged = true;
	Rep.RfHeavyMonsterPoints+=Amount;
	if( MyStatsObject!=None )
		MyStatsObject.fHM+=Amount;
	DelayedStatCheck();
}

function AddPipeBombDamage(int Amount)
{
	bHasChanged = true;
	Rep.RPipeBombDamageStat+=Amount;
	if( MyStatsObject!=None )
		MyStatsObject.dmPB+=Amount;
}

function AdddmHMDamage(int Amount)
{
	bHasChanged = true;
	Rep.RdmHeavyMonsterPoints+=Amount;
	if( MyStatsObject!=None )
		MyStatsObject.dmHM+=Amount;
	DelayedStatCheck();
}
//------------------------------SH


// Allow no default functionality with the stats.
function OnStatsAndAchievementsReady();
function PostNetBeginPlay();
function InitializeSteamStatInt(int Index, int Value);
function SetSteamAchievementCompleted(int Index);
event SetLocalAchievementCompleted(int Index);
function ServerSteamStatsAndAchievementsInitialized();
function UpdateAchievementProgress();
function int GetAchievementCompletedCount();
event OnPerkAvailable();
function WonLongGame(string MapName, float Difficulty);
function AddDemolitionsPipebombKill();
function AddSCARKill();
function AddCrawlerKilledInMidair();
function Killed8ZedsWithGrenade();
function Killed10ZedsWithPipebomb();
function KilledHusk(bool bDamagedFriendly);
function AddMac10BurnDamage(int Amount);
function AddGorefastBackstab();
function ScrakeKilledByFire();
function KilledCrawlerWithCrossbow();
function OnLARReloaded();
function AddStalkerKillWithLAR();
function KilledHuskWithPistol();
function AddDroppedTier3Weapon();
function Survived10SecondsAfterVomit();
function CheckChristmasAchievementsCompleted();
function PlayerDied();
//function KilledPatriarch(bool bPatriarchHealed, bool bKilledWithLAW, bool bSuicidalDifficulty, bool bOnlyUsedCrossbows);
//function KilledPatriarch(bool bPatriarchHealed, bool bKilledWithLAW, bool bSuicidalDifficulty, bool bOnlyUsedCrossbows, bool bClaymore);
function KilledPatriarch(bool bPatriarchHealed, bool bKilledWithLAW, bool bSuicidalDifficulty, bool bOnlyUsedCrossbows, bool bClaymore, string MapName);

function Destroyed()
{
	if( Rep!=None )
	{
		if( MyStatsObject!=None )
			MyStatsObject.SetCustomValues(Rep.CustomLink);
		Rep.Destroy();
		Rep = None;
	}
	if( PlayerOwner!=None && !PlayerOwner.bDeleteMe )
	{
		// Was destroyed mid-game for random reason, respawn.
		MutatorOwner.PendingPlayers[MutatorOwner.PendingPlayers.Length] = PlayerOwner;
		MutatorOwner.SetTimer(0.1,false);
	}
	Super.Destroyed();
}

Auto state PlaytimeTimer
{
Begin:
	while( true )
	{
		Sleep(1.f);
		if( bStatsReadyNow && !PlayerOwner.PlayerReplicationInfo.bOnlySpectator )
		{
			++Rep.TotalPlayTime;
			if( MyStatsObject!=None )
				++MyStatsObject.TotalPlayTime;
		}
	}
}

defaultproperties
{
     bInitialized=True
     bUsedCheats=True
     RemoteRole=ROLE_None
     bNetNotify=False
}
